﻿#pragma once
#include <string>
#include <vector>
#include <set>
#include <QString>
#include "baseoption_global.h"

#define MarketDateTime_Morning 1 // 上午行情段
#define MarketDateTime_Afternoon 2 // 下午行情段
#define MarketDateTime_Evening 3 // 晚上行情段
#define NoMarketDateTime_Afternoon 4 // 下午的非行情段
#define NoMarketDateTime_Evening 5  // 晚上的非行情段

#define QuantityDays 16

namespace CTPTm
{
	// 返回这个时间所属的时间段
	int BASEOPTION_EXPORT DateTimeSectionTag(const std::string& pDtStr);
	// 得到当前时间段的起止时间
	void BASEOPTION_EXPORT GetSegmentRange(const tm &pDateTime, tm &outBeginDt, tm &outEndDt);
	// 获取时间段的行情时间
	void BASEOPTION_EXPORT GetSegmentMarketRange(const tm &pDateTime, tm &outBeginDt, tm &outEndDt);
	// 获得上一根时间段的行情时间
	void BASEOPTION_EXPORT GetPreviousSegmentMarketRange(const tm &pDateTime, tm &outBeginDt, tm &outEndDt);
	// 获得下一根时间段的行情时间
	void BASEOPTION_EXPORT GetNextSegmentMarketRange(const tm &pDateTime, tm &outBeginDt, tm &outEndDt);
	// 返回这个时间所属的时间段 0属于上午段 1下午段 2晚上段
	int BASEOPTION_EXPORT DateTimeSectionTag(const tm& pDt);

	// 将时间范围转成字符串数组
	void BASEOPTION_EXPORT DateRangeToStringList(time_t pBeginDay, time_t pEndDay, std::vector<std::string> &outDayStr);
	// 将时间范围转成每天的范围
	void BASEOPTION_EXPORT DateRangeToDays(time_t pBeginTime, time_t pEndTime, std::vector<std::pair<time_t, time_t>> &outDays);
	// 将时间范围转成日期范围
	void BASEOPTION_EXPORT DateRangeToDays(time_t pBeginDay, time_t pEndDay, std::vector<time_t> &outDays);

	// 返回行情时间所属日期
	std::string BASEOPTION_EXPORT GetMarketDayStr(time_t pTime);
	std::string BASEOPTION_EXPORT GetMarketDayStr(tm pDateTime);
	tm BASEOPTION_EXPORT GetMarketDay(tm pDateTime);

	// 当前时间往前推n个工作日的时间
	tm BASEOPTION_EXPORT GetWorkDayTimeBeforeDaysLen(tm curDateTime, int pDays);

	struct BASEOPTION_EXPORT DayRange
	{
		time_t RangeBegin;
		time_t RangeEnd;
		bool operator<(const struct DayRange & right)const;   //重载<运算符
	};

	class BASEOPTION_EXPORT HolidayManager
	{
	public:
		enum DayType
		{
			Unknown, // 未知 一般不会有这种情况
			Holiday, // 假期
			WorkDay  // 工作日
		};
		HolidayManager();
		// 设置保存节日列表和特殊工作日
		void SaveHolidayAndSpecialDay(const std::set<DayRange> &pHoliday, const std::set<DayRange> &pSpecialWorkDay);
		// 返回节日列表
		const std::set<DayRange> &GetHolidayList() { return m_holidayList; }
		// 返回工作日列表
		const std::set<DayRange> &GetSpecialWorkDayList() { return m_specialWorkDayList; }
		// 判断时间段是否是行情时间
		bool IsMarketTime(const time_t &pDateTime);
		// 判断今日是否有行情
		bool IsMarketDay(const time_t &pDateTime);
	private:
		// 初始化假期时间段
		void initHolidayList();
		// 解析时间段字符串，并返回时间范围和假期或工作日的标记
		DayType getDayRange(const QString &pStr, DayRange &outRange);
		// DayRange转字符串
		QString dayRangeToStr(char pTag, const DayRange &pRange);
		// 是否在官方节日中
		bool isInSpecialHoliday(const time_t &pDateTime);
		// 是否是周末
		bool isInWeekend(const time_t &pDateTime);

		// 节日列表
		std::set<DayRange> m_holidayList;
		// 周末工作日列表
		std::set<DayRange> m_specialWorkDayList;
	};


}